package com.dateConstruction._04_seqQueue;

public final class CirSeqQueue<T> implements Queue<T> {
    
    // 存储队列数据元素的数组
    private Object[] element;
    
    // 常量，指定element数组容量最小值
    private static final int MINCAPACITY = 16;
    
    // 队列头与尾的下标
    private int front, rear;
    
    // 创建空队列
    public CirSeqQueue(int length) {
        if (length < MINCAPACITY) {
            length = MINCAPACITY;
        }
        this.element = new Object[length];
        this.front = this.rear = 0;
    }
    
    // 判空
    public boolean isEmpty() {
        // TODO Auto-generated method stub
        return this.front == this.rear;
    }

    // 入队
    public boolean add(Object x) {
        // TODO Auto-generated method stub
        if (x == null) {
            return false;
        }
        // 如果队列满，则扩充队列
        if (this.front == (this.rear + 1) % this.element.length) {
            Object[] temp = this.element;
            this.element = new Object[temp.length * 2];
            for (int i = this.front; i < this.rear; i++) {
                this.element[i] = temp[i];
            }
        }
        // 尾插入
        this.element[this.rear] = x;
        this.rear = (this.rear + 1) % this.element.length;
        return true;
    }

    // 返回队列头元素
    public T peek() {
        // TODO Auto-generated method stub
        return this.isEmpty() ? null : (T) this.element[front];
    }

    // 出队，返回出队元素
    public T poll() {
        // TODO Auto-generated method stub
        if (this.isEmpty()) {
            return null;
        }
        T temp = (T) this.element[front];
        this.front = (front + 1) % this.element.length;
        return temp;
    }
    
    public String toString() {
        if (this.isEmpty()) {
            return null;
        }
        String str = "{";
        for (int i = this.front; i < this.rear - 1; i++) {
            str += this.element[i] + ", ";
        }
        str += this.element[(rear - 1 + this.element.length) % this.element.length];
        return str + "}";
    }
    
    // 返回队中元素个数
    public int size() {
        int temp = rear - front;
        if (temp >= 0) {
            return temp;
        } else {
            return this.element.length + temp;
        }
    }
    
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        CirSeqQueue<Integer> q = new CirSeqQueue<Integer>(0);
        q.add(0);
        q.add(1);
        q.add(2);
        q.add(3);
        System.out.println(q);
        System.out.println(q.poll() + ", " + q.poll() + ", " + q.poll());
        System.out.println(q);
        
        System.out.println("测试size()方法：");
        System.out.println(q.size());
    }
}
